package com.zbkj.crmeb.block.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.MyRecord;
import com.common.PageParamRequest;
import com.constants.Constants;
import com.exception.CrmebException;
import com.github.pagehelper.PageHelper;
import com.utils.DateUtil;
import com.utils.vo.dateLimitUtilVo;
import com.zbkj.crmeb.block.dao.IncrementDao;
import com.zbkj.crmeb.block.dao.IncrementHistoryDao;
import com.zbkj.crmeb.block.model.Increment;
import com.zbkj.crmeb.block.model.IncrementHistory;
import com.zbkj.crmeb.block.request.IncrementSearchRequest;
import com.zbkj.crmeb.block.service.BlockService;
import com.zbkj.crmeb.category.model.Category;
import com.zbkj.crmeb.store.model.StoreOrder;
import com.zbkj.crmeb.store.model.StoreProduct;
import com.zbkj.crmeb.store.service.StoreOrderInfoService;
import com.zbkj.crmeb.store.service.StoreProductService;
import com.zbkj.crmeb.store.vo.StoreOrderInfoVo;
import com.zbkj.crmeb.system.service.SystemConfigService;
import com.zbkj.crmeb.user.dao.UserDao;
import com.zbkj.crmeb.user.model.User;
import com.zbkj.crmeb.user.request.UserOperateFundsRequest;
import com.zbkj.crmeb.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.constants.Constants.USER_BILL_TYPE_PAY_PRODUCT;
import static com.constants.Constants.USER_BILL_TYPE_TRANSFER_IN;

@Slf4j
@Service
public class BlockServiceImpl extends ServiceImpl<IncrementDao, Increment> implements BlockService {
    @Autowired
    private IncrementDao dao;

    @Autowired
    private IncrementHistoryDao historyDao;

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private StoreOrderInfoService storeOrderInfoService;

    @Autowired
    private StoreProductService storeProductService;

    @Autowired
    private UserService userService;

    @Resource
    private UserDao userDao;

    @Override
    public List<Increment> getList(IncrementSearchRequest request, PageParamRequest pageParamRequest) {
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        LambdaQueryWrapper<Increment> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        Increment increment = new Increment();
        BeanUtils.copyProperties(request, increment);
        if (null != increment.getOrderId()) {
            lambdaQueryWrapper.eq(Increment::getOrderId, increment.getOrderId());
        }
        lambdaQueryWrapper.orderByDesc(Increment::getId);
        return dao.selectList(lambdaQueryWrapper);
    }

    @Transactional
    public void calculateIncrement(StoreOrder order) {
        List<StoreOrderInfoVo> orderInfoList = storeOrderInfoService.getOrderListByOrderId(order.getId());
        List<Integer> productIds = orderInfoList.stream().map(StoreOrderInfoVo::getProductId).collect(Collectors.toList());
        if (productIds.size() > 0) {
            List<StoreProduct> products = storeProductService.getListInIds(productIds);

            Double profit = products.stream().mapToDouble(e -> e.getPrice().subtract(e.getCost()).doubleValue()).sum();
            BigDecimal price = null;
            BigDecimal cost = null;

            if (products.size() == 1) {
//                price = products.get(0).getPrice();
                price = order.getPayPrice().subtract(order.getPayPostage());//实际支付金额减去邮费
                cost = products.get(0).getCost();

                if (price.doubleValue() < cost.doubleValue()) return;//亏本
            }

            LambdaQueryWrapper<Increment> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            List<Increment> result = dao.selectList(lambdaQueryWrapper.eq(Increment::getCurrent, true));
            String commission = systemConfigService.getValueByKey(Constants.CONFIG_KEY_TOKEN_COMMISSION_PERCENT);
            String increment = systemConfigService.getValueByKey(Constants.CONFIG_KEY_TOKEN_INCREMENT_PERCENT);
            String increment2d = systemConfigService.getValueByKey(Constants.CONFIG_KEY_TOKEN_INCREMENT2D_PERCENT);
            String currentInit = systemConfigService.getValueByKey(Constants.CONFIG_KEY_TOKEN_INIT_TOKEN_NUM);
            if (result.size() == 1) {
                Increment before = result.get(0);
                Increment current = new Increment();
                current.initByPre(price, cost, order.getOrderId(), before.getAfterIncrementToken(), before.getAfterIncrementPrice());
                current.calculate(new BigDecimal(profit), new BigDecimal(commission), new BigDecimal(increment), new BigDecimal(increment2d),
                        before.getInitToken(), new BigDecimal(currentInit));

                saveFoundsToken(order.getUid(), current.getIncrementToken(), order.getOrderId(), Constants.ORDER_STATUS_STR_OWNER_TAKE, USER_BILL_TYPE_PAY_PRODUCT);

                User user = userDao.selectById(order.getUid());

                if (user.getSpreadUid() != null) {
                    User parent = userDao.selectById(user.getSpreadUid());
                    if (parent != null)
                        saveFoundsToken(parent.getUid(), current.getIncrement2dToken(), order.getOrderId(), Constants.ORDER_STATUS_STR_FRIEND_TAKE, USER_BILL_TYPE_TRANSFER_IN);
                }

                current.setOrderType("普通订单");
                if (order.getPinkId() != null && order.getPinkId() > 0) {
                    current.setOrderType("拼团订单");
                }
                if (order.getCombinationId() != null && order.getCombinationId() > 0) {
                    current.setOrderType("拼团商品订单");
                }
                if (order.getSeckillId() != null && order.getSeckillId() > 0) {
                    current.setOrderType("描述订单");
                }
                if (order.getCouponId() != null && order.getCouponId() > 0) {
                    current.setOrderType("优惠券订单");
                }
                if (order.getBargainId() != null && order.getBargainId() > 0) {
                    current.setOrderType("砍价订单");
                }


                current.setCurrent(true);
                dao.insert(current);
                before.setCurrent(false);
                dao.updateById(before);
            } else {
                throw new CrmebException("当前记录有且仅有一条");
            }
        }
    }

    @Override
    public void saveIncrementEveryDay() {
        LambdaQueryWrapper<Increment> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        List<Increment> result = dao.selectList(lambdaQueryWrapper.eq(Increment::getCurrent, true));
        if (result.size() == 1) {
            Increment current = result.get(0);
            if (historyDao.selectOne(new LambdaQueryWrapper<IncrementHistory>().eq(IncrementHistory::getTimeStr,
                    DateUtil.getSimpleTodayStr())) == null) {
                IncrementHistory history = new IncrementHistory().setCategory("daily").setPrice(current.getAfterIncrementPrice())
                        .setTimeStr(DateUtil.getSimpleTodayStr());
                historyDao.insert(history);
            }
        }
    }

    @Override
    public Map<Object, Object> trendHistory(String date) {
        Map<Object, Object> map = new HashMap<>();
        QueryWrapper<IncrementHistory> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(date)) {
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(date);
            queryWrapper.between("create_time", dateLimit.getStartTime(), dateLimit.getEndTime());
        }
        queryWrapper.orderByAsc("create_time");
        List<IncrementHistory> list = historyDao.selectList(queryWrapper);
        if (list.size() < 1) {
            return map;
        }

        for (IncrementHistory history : list) {
            map.put(DateUtil.dateToStr(history.getCreateTime(), Constants.DATE_FORMAT_DATE), history.getPrice());
        }
        return map;
    }

    @Override
    public BigDecimal getCurrentPrice() {
        LambdaQueryWrapper<Increment> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        List<Increment> result = dao.selectList(lambdaQueryWrapper.eq(Increment::getCurrent, true));
        if (!result.isEmpty()) return result.get(0).getAfterIncrementPrice();
        String currentPrice = systemConfigService.getValueByKey(Constants.CONFIG_KEY_TOKEN_INIT_TOKEN_PRICE);
        return BigDecimal.valueOf(Double.valueOf(currentPrice));
    }

    // 获取额外赠送积分
    private void saveFoundsToken(Integer uid, BigDecimal token, String orderId, String title,
                                 String type) {
        UserOperateFundsRequest userOperateFundsRequest = new UserOperateFundsRequest();
        userOperateFundsRequest.setValue(token);
        userOperateFundsRequest.setLinkId(orderId);
        userOperateFundsRequest.setFoundsType(type);
        userOperateFundsRequest.setUid(uid);
        userOperateFundsRequest.setTitle(title);
        userOperateFundsRequest.setFoundsCategory(Constants.USER_BILL_CATEGORY_TOKEN);
        userOperateFundsRequest.setType(1);
        userService.updateFounds(userOperateFundsRequest, true);
    }

    @Autowired
    public Boolean isOpen() {
        String isOpen = systemConfigService.getValueByKey(Constants.CONFIG_KEY_TOKEN_IS_OPEN);
        log.warn("open config is {}", isOpen);
        return !StringUtils.isEmpty(isOpen) && isOpen.equals("1");
    }
}
